
/* <<< COPYRIGHT START >>>
 * Copyright 2006-Present OxygenSoftwareLibrary.com
 * Licensed under the GNU Lesser General Public License.
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * @author: Ugorji Dick-Nwoke
 * <<< COPYRIGHT END >>>
 */


package oxygen.tool.wlfacade;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorFactory;
import javax.naming.Context;
import javax.naming.InitialContext;

import weblogic.management.MBeanHome;
import weblogic.management.runtime.ServerRuntimeMBean;


public class WLScriptConnectionImpl implements WLScriptConnection {

  private WLConnectionData wlconndata;
  private String serverName = null;
  private String domainName = null;
  private Map mbsmap = new HashMap();
  private MBeanHome mbhChange = null;
  private boolean adminserver = false;
  private Object commombs = null;
  private InitialContext ictx = null;
  private boolean wls90 = false;
  
  public WLScriptConnectionImpl(WLConnectionData _wlconndata) throws Exception {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");

    env.put(Context.PROVIDER_URL, _wlconndata.url);
    if (_wlconndata.username != null) {
      env.put(Context.SECURITY_PRINCIPAL, _wlconndata.username);
    }
    if (_wlconndata.password != null) {
      env.put(Context.SECURITY_CREDENTIALS, _wlconndata.password);
    }
    
    System.out.print("Looking up initial context ... ");
    long currtime = System.currentTimeMillis();
    ictx = new InitialContext(env);
    System.out.println("retrieved [in " + (System.currentTimeMillis() - currtime) + "ms]");

    // add pre-90 mbeanservers
    MBeanHome adminhome = (MBeanHome)ictx.lookup(MBeanHome.ADMIN_JNDI_NAME);
    MBeanHome localhome = (MBeanHome)ictx.lookup(MBeanHome.LOCAL_JNDI_NAME);
    
    mbsmap.put("local", localhome.getMBeanServer());
    mbsmap.put("admin", adminhome.getMBeanServer());

    ServerRuntimeMBean srmb = (ServerRuntimeMBean)localhome.getMBeansByType("ServerRuntime").iterator().next();
    serverName = srmb.getName();
    domainName = localhome.getDomainName();
    adminserver = srmb.isAdminServer();

    if(adminserver) {
      mbhChange = adminhome;
    } 
    
    try {
      commombs = WLScriptHelper.getCommoMBS(serverName, _wlconndata.url, _wlconndata.username, _wlconndata.password);
      if(commombs != null) {
        mbsmap.put("commo", commombs);
      }
    } catch(Throwable exc) { //NamingException exc) {
      //this is fine ... since some of the MBeanServers might not exist yet (especially pre diablo)
      System.out.println("Ignoring Exception caught looking up COMMO MBeanServer: " + exc);
      //exc.printStackTrace(System.out);
    }
    
    //add 90 mbeanservers
    Map m = new HashMap();
    m.put("domainruntime", "weblogic.management.mbeanservers.domainruntime");
    m.put("runtime", "weblogic.management.mbeanservers.runtime");
    m.put("edit", "weblogic.management.mbeanservers.edit");
    env.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
    for(Iterator itr = m.keySet().iterator(); itr.hasNext(); ) {
      String key = (String)itr.next();
      try {
        //MBeanServer mbs = (MBeanServer)ictx.lookup((String)m.get(key));
        String urlstr = "service:jmx:" + _wlconndata.url + "/jndi/" + m.get(key);
        //System.out.println("service url string: " + urlstr);
        Object mbs = WLScriptHelper.getMBSConn(urlstr, env);
        if(mbs != null) {
          mbsmap.put(key, mbs);
        }
      } catch(Throwable exc) { //NamingException exc) {
        //this is fine ... since some of the MBeanServers might not exist yet (especially pre diablo)
        System.out.println("Ignoring Exception caught looking up MBeanServer for key: " + key + ": " + exc);
        //exc.printStackTrace(System.out);
      } 
    }
    if(mbsmap.containsKey("runtime")) {
      wls90 = true;
    }
    
    System.out.println("Login completed [in " + (System.currentTimeMillis() - currtime) + "ms]");
    this.wlconndata = _wlconndata;
    
  }
  
  public String getServerName() {
    return serverName;
  }
  
  public String getDomainName() {
    return domainName;
  }
  
  public Object getMBS(String logicalname) throws Exception {
    return (MBeanServer)mbsmap.get(logicalname);
  }
  
  public Object getChangeMBS() throws Exception {
    Object mbs = null;
    if(adminserver) {
      if(wls90) {
        mbs = mbsmap.get("edit");
      } else {
        mbs = mbsmap.get("local");
      }
    }
    return mbs;
  }
  
//  public void deleteMBean(ObjectName cmo) throws Exception {
//    mbhChange.deleteMBean(cmo);
//  }
//  
//  public ObjectName createMBean(ObjectName cmo, String type, String name) throws Exception {
//    ConfigurationMBean cmbean = null;
//    if(cmo != null) {
//      cmbean = (ConfigurationMBean)mbhChange.getMBean(cmo);
//    }
//    WebLogicMBean wmbean = mbhChange.createAdminMBean(name, type, domainName, cmbean);
//    ObjectName cmo2 = wmbean.getObjectName();
//    return cmo2;
//  }
//  
  
  public String getWLVersion() {
    return "";
  }
  
  public WLConnectionData getWLConnectionData() {
    return wlconndata.copy();
  }
  
  public InitialContext getInitialContext() {
    return ictx;
  }
  
  public Object getCommoMBS() throws Exception {
    return commombs;
  }
  
  public boolean isAdminServer() {
    return adminserver;
  }
  
  public Map getAllMBS() throws Exception {
    return Collections.unmodifiableMap(mbsmap);
  }

  public void close() throws Exception {
    ictx.close();
  }
  
  public boolean isAtOrAfterVer90() {
    return wls90;
  }

}





// == to get the DeployerRuntimeMBean ==
//MBeanHome mbh = wlctx.getConnection().getMBeanHomeForChange();
//DeployerRuntimeMBean dmb = DeployerRuntime.getDeployerRuntime(mbh);
//return dmb.getObjectName();
